
#include "DisplayDriver.h" 

#if ENABLE_LCD

volatile UINT8	gv_ucIsTransmitting;

static void 	Lcd_Init(void);
static UINT8	Lcd_IsTransmitting(void);
static void 	Lcd_SetBacklight(UINT8 value);
static void 	Lcd_GetFrameBuf(void ** fb);
static void 	Lcd_On(void);
static void 	Lcd_Off(void);
static void 	Lcd_DrawPoint(UINT16 Xpos, UINT16 Ypos, UINT32 RGBCode);
static void 	Lcd_FillColor(UINT16 Xpos, UINT16 Ypos,UINT16 Width, UINT16 Height,UINT32 color);
static void 	Lcd_DrawBitmap(UINT16 Xpos, UINT16 Ypos,UINT16 Width, UINT16 Height,UINT8 *pcolor);

LcdDriver_T g_lcdDriver = {
	.info 				= &g_lcdInfo,
	.timing 			= &g_lcdTiming,
	.init 				= Lcd_Init,
	.isTransmitting		= Lcd_IsTransmitting,
	.getFrameBuffer 	= Lcd_GetFrameBuf,
	.on 				= Lcd_On,
	.off 				= Lcd_Off,
	.setBacklight 		= Lcd_SetBacklight,
	.drawPoint 			= Lcd_DrawPoint,
	.readPoint 			= NULL,
	.fillColor 			= Lcd_FillColor,
	.drawBitmap 		= Lcd_DrawBitmap,
	.transCompleteCall	= NULL,
};

static void Lcd_SetDisplayWindow(UINT16 _xPos, UINT16 _yPos, UINT16 _width, UINT16 _height)
{
	UINT16 twidth,theight;

	twidth=_xPos+_width;
	theight=_yPos+_height;

	Lcd_WReg(g_lcdDriver.info->setXCmd);
	Lcd_WData(_xPos>>8);
	Lcd_WData(_xPos&0XFF);
	Lcd_WData(twidth>>8);
	Lcd_WData(twidth&0XFF);
	
	Lcd_WReg(g_lcdDriver.info->setYCmd);
	Lcd_WData(_yPos>>8);
	Lcd_WData(_yPos&0XFF);
	Lcd_WData(theight>>8);
	Lcd_WData(theight&0XFF);
	
	
	Lcd_WReg(g_lcdDriver.info->wRamCmd);
	SET_DATA();
	
}

static void Lcd_DrawPoint(UINT16 _xPos, UINT16 _yPos, UINT32 _RGBCode)
{
	while(gv_ucIsTransmitting)	
	{
	
	}
	Lcd_WReg(g_lcdDriver.info->setXCmd);
	Lcd_WData((_xPos >> 8) & 0xFF);
	Lcd_WData(_xPos & 0xFF);
	Lcd_WData((_xPos >> 8) & 0xFF);
	Lcd_WData(_xPos & 0xFF);
	Lcd_WReg(g_lcdDriver.info->setYCmd);
	Lcd_WData((_yPos >> 8) & 0xFF);
	Lcd_WData(_yPos & 0xFF);
	Lcd_WData((_yPos >> 8) & 0xFF);
	Lcd_WData(_yPos & 0xFF);
	Lcd_WReg(g_lcdDriver.info->wRamCmd);
	Lcd_WData16(_RGBCode);
}

static UINT8 Lcd_IsTransmitting(void)
{
	if(gv_ucIsTransmitting)
		return LCD_STATUS_TRANSMITTING;
	else
		return LCD_STATUS_IDLE;
}

static UINT16 gs_color;

static void Lcd_FillColor(UINT16 _xPos, UINT16 _yPos,UINT16 _width, UINT16 _height,UINT32 _color)
{
//	while(gv_ucIsTransmitting)	
	{
	
	}
	DISPLAY_LOG("Lcd_FillColor\r\n");
	gv_ucIsTransmitting = 1;

	UINT32 index=0,temp;
	UINT32 totalpoint=_width;

	
	Lcd_SetDisplayWindow(_xPos, _yPos, _width-1,_height-1);
	
		totalpoint *= _height;
		gs_color = _color;
	
		SET_CLK();
		for(index=0;index<totalpoint;index++)
		{
			temp = (Lcd_Data1_Port->ODR & 0xff00);
			temp |= ((gs_color>>8) & 0xff);
			Lcd_Data1_Port->ODR = temp;
//			Lcd_Data1_Port->BSRR = ((~(gs_color>>8)) << 16) | (gs_color>>8);
//			CLR_CLK();
//			Lcd_DelayUs(LCD_DELAY);
//			SET_CLK();
//			Lcd_DelayUs(LCD_DELAY);
			Lcd_Data_Port->BSRR = ((~(gs_color&0xff)) << 16) | (gs_color&0xff);
			CLR_CLK();
			Lcd_DelayUs(LCD_DELAY);
			SET_CLK();
			Lcd_DelayUs(LCD_DELAY);
		}
		gv_ucIsTransmitting = 0;
		if(g_lcdDriver.transCompleteCall != NULL)
				g_lcdDriver.transCompleteCall();

}

static void Lcd_DrawBitmap(UINT16 _xPos, UINT16 _yPos,UINT16 _width, UINT16 _height,UINT8 *_pcolor)
{
	while(gv_ucIsTransmitting)	
	{
	
	}
	gv_ucIsTransmitting = 1;

	UINT32 totalpoint=_width;

		UINT16 *color = (UINT16 *)_pcolor;

	totalpoint *= _height;

	Lcd_SetDisplayWindow(_xPos,_yPos,_width-1,_height-1);

		uint32_t index = 0;
		SET_CLK();
		for(index=0;index<totalpoint;index++)
		{
			Lcd_Data_Port->BSRR = ((~(color[index]>>8)) << 16) | (color[index]>>8);
			CLR_CLK();
			SET_CLK();
			Lcd_Data1_Port->BSRR = ((~(color[index]&0xff)) << 16) | (color[index]&0xff);
			CLR_CLK();
			SET_CLK();
		}
		gv_ucIsTransmitting = 0;
		if(g_lcdDriver.transCompleteCall != NULL)
			g_lcdDriver.transCompleteCall();

}

static void Lcd_SetBacklight(UINT8 _value)
{
    if(_value>100)
		_value = 100;
	DISPLAY_LOG("Backlight = %d\r\n",_value);
	Board_LcdBacklight(_value);
}

static void Lcd_GetFrameBuf(void ** fb)
{
	*fb = NULL;
}

static void Lcd_On(void)
{
	Lcd_WReg(LCD_EXIT_SLEEP);
	Lcd_WReg(LCD_DISPLAY_ON);
	Lcd_SetBacklight(80);
}

static void Lcd_Off(void)
{
	Lcd_WReg(LCD_DISPLAY_OFF);
	Lcd_WReg(LCD_ENTER_SLEEP);
	Lcd_SetBacklight(0);
}

static void Lcd_Rest(void)
{
	RST_HI();
    HAL_Delay(50);
	RST_LOW();
    HAL_Delay(50);
	RST_HI();
    HAL_Delay(120);
}
static void Lcd_Init(void)
{
	gv_ucIsTransmitting = 0;

	if(g_lcdInfo.interType != LCD_DRIVE_TYPE)
	{
		ERROR_MSG("Lcd Interface type mismatch\r\n");
		return;
	}
//	Board_LcdPortInit();
	DISPLAY_LOG("Lcd_IO_Init\r\n");

    Lcd_Rest();

    SET_RD();
	CLR_CS();
	
	Lcd_Drive_Init();					
	DISPLAY_LOG("Lcd_Drive Init Ok\r\n");

	Board_LcdBacklightPortInit();
	DISPLAY_LOG("Lcd_Backlight Init OK\r\n");
	
	SYS_LOG("Lcd Init Ok\r\n");
}
DEV_INIT(Lcd_Init);


#endif
